package com.ziq.zcamp.place

import android.widget.Toast
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.LogUtils
import com.gmlive.camp.data.exception.LocalException
import com.ziq.base.extension.launchWithTryAsynchronous
import com.ziq.zcamp.R
import com.ziq.zcamp.api.request.act.CampActivitiesListParam
import com.ziq.zcamp.api.request.camp.*
import com.ziq.zcamp.api.respond.post.PostingListRespond
import com.ziq.zcamp.api.service.*
import com.ziq.zcamp.bean.activities.ActivitiesInfo
import com.ziq.zcamp.bean.coupon.CouponCampOnline
import com.ziq.zcamp.bean.place.GreenCampAgreeStatus
import com.ziq.zcamp.bean.place.PlaceDetail
import com.ziq.zcamp.bean.post.ImageInfo
import com.ziq.zcamp.bean.post.PostingDetail
import com.ziq.zcamp.bean.post.PostingList
import com.ziq.zcamp.bean.product.PlaceProductList
import com.ziq.zcamp.manager.GlobalContextManager
import com.ziq.zcamp.manager.UserManager
import com.ziq.zcamp.util.encrypt.AesVr
import com.ziq.zcamp.view.StatusView
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import javax.inject.Inject

@HiltViewModel
class PlaceDetailViewModel @Inject constructor() : ViewModel() {

    @Inject
    lateinit var mPostingService: PostingService

    @Inject
    lateinit var mActivityService: ActivityService

    @Inject
    lateinit var mCampService: CampService

    val statusShow = MutableLiveData<Int>()
    val dimiss = MutableLiveData<Boolean>()
    val productList = MutableLiveData<PlaceProductList>()
    val actList = MutableLiveData<List<ActivitiesInfo>>()
    val punchRecommendList = MutableLiveData<List<PostingDetail>?>()

    val placeDetail = MutableLiveData<PlaceDetail>()
    val couponList = MutableLiveData<List<CouponCampOnline>>()
    val greenCampAgreeStatus = MutableLiveData<GreenCampAgreeStatus>()

    val listRequestFinished = MutableLiveData<Boolean>()
    val listHasMore = MutableLiveData<Boolean>()
    val list = MutableLiveData<MutableList<PostingDetail>>()

    val postingList = MutableLiveData<PostingList>()

    var detailId :Int = 0

    var page = 1
    var pageSize = 20
    var aesVr = AesVr()

    fun requestDetail(id: Int) {

        launchWithTryAsynchronous(whenTry = {
            val respond = mCampService.placeDetail(PlaceDetailParam().apply {
                this.camp_id = id
            }.queryMap).request()

            val isFieldCamp = respond.data?.camp?.camp_type == 2
            if(isFieldCamp){
                if(UserManager.instance.isLogin.value == true){
                    val greenCampRespond = mCampService.greenCampAgreeStatus(GreenCampAgreeStatusParam().queryMap).request()
                    withContext(Dispatchers.Main){
                        greenCampAgreeStatus.value = greenCampRespond.data
                    }
                } else {
                    withContext(Dispatchers.Main){
                        greenCampAgreeStatus.value = GreenCampAgreeStatus().apply {
                            status = 0
                        }
                    }
                }
            }

            withContext(Dispatchers.Main){
                respond.let {
                    if (it.data != null){
                        if(it.data!!.camp?.vr?.exist_vr == true){
                            it.data!!.camp?.vr?.url = aesVr.decode(it.data!!.camp?.vr?.url)
                        }
                        if (it.data!!.camp?.pictures?.isNotEmpty() == true){
                            var imageList: List<ImageInfo> =  mutableListOf<ImageInfo>()
                            if (it.data!!.camp?.pictures?.isNotEmpty() == true){
                                it.data!!.camp?.pictures?.let {
                                    imageList = GsonUtils.fromJson(it, GsonUtils.getListType(ImageInfo::class.java))
                                }
                            }
                            it.data!!.camp?.images = imageList
                        }
                        placeDetail.postValue(it.data)
                        statusShow.postValue(StatusView.IDLE)
                    }else {
                        statusShow.postValue(StatusView.NET_ERROR)
                    }
                }
            }

        }, whenCatch = {
            withContext(Dispatchers.Main){
                try {
                    when(it){
                        is LocalException -> {
                            Toast.makeText(GlobalContextManager.appContext!!, GlobalContextManager.getString(R.string.all_net_error), Toast.LENGTH_SHORT).show()
                            statusShow.postValue(StatusView.NET_ERROR)
                        }
                        is NetWorkException -> {
                            if(it.errorCode == 1006){
                                statusShow.postValue(StatusView.NO_DATA)
                                Toast.makeText(GlobalContextManager.appContext!!, it.message ?: "", Toast.LENGTH_SHORT).show()
                                dimiss.postValue(true)
                            } else {
                                Toast.makeText(GlobalContextManager.appContext!!, GlobalContextManager.getString(R.string.all_net_error), Toast.LENGTH_SHORT).show()
                                statusShow.postValue(StatusView.NET_ERROR)
                            }
                        }
                        else -> {
                            Toast.makeText(GlobalContextManager.appContext!!, GlobalContextManager.getString(R.string.all_net_error), Toast.LENGTH_SHORT).show()
                            statusShow.postValue(StatusView.NET_ERROR)
                        }
                    }
                }catch (e:Exception){}
            }
        })
    }

    fun onRefresh(showProgress: Boolean = false, requestPosting: Boolean = true){

        if(showProgress){
            statusShow.postValue(StatusView.LOADING)
        }
        requestDetail(detailId)
        requestProductList()
        requestActList()
        if(requestPosting){
            page = 1
            requestList()
        }

    }

    fun onLoadMore(){
        requestList()
    }

    fun onRefreshPosting(){
        page = 1
        requestList()
    }

    fun requestList(
        onSuccess: ((result: PostingListRespond) -> Unit)? = {
            if(page == 1){
                postingList.postValue(it.data)
            }

            if (it.data != null){
                val tempList = mutableListOf<PostingDetail>()
                if(page != 1 && list.value != null){
                    tempList.addAll(list.value!!)
                }
                if(it.data?.list?.isNotEmpty() == true){
                    tempList.addAll(it.data!!.list!!)
                }
                list.postValue(tempList)

                page++
                if(it?.data?.has_more == true){
                    listHasMore.postValue(true)
                } else {
                    listHasMore.postValue(false)
                }
            }else {
                listHasMore.postValue(false)
            }
            listRequestFinished.postValue(true)
        },
        onFail: ((result: String) -> Unit)? = {
            listRequestFinished.postValue(true)
        }) {

        launchWithTryAsynchronous(whenTry = {
            val respond = mCampService.campPunchList(CampPunchListParam().apply {
                this.camp_id = detailId
                this.page = this@PlaceDetailViewModel.page
                this.page_size = pageSize
            }).request()

            if(respond.data?.list?.isNotEmpty() == true){
                for(item in respond.data?.list!!){
                    item.parseData()
                }
            }

            withContext(Dispatchers.Main){
                onSuccess?.invoke(respond)
            }
        }, whenCatch = {
            withContext(Dispatchers.Main){
                onFail?.invoke("$it")
            }
        })
    }

    var count = 0
    fun requestProductList() {
        launchWithTryAsynchronous(whenTry = {
            val respond = mCampService.placeDetailProductList(PlaceDetailProductListParam().apply {
                camp_id = detailId
                page = 1
                page_size = 10
            }.queryMap).request()

            if(respond.data?.list?.isNotEmpty() == true){
                for(item in respond.data?.list!!){
                    item.parseData()
                }
            }

            val couponRespond = mCampService.couponCampOnlineList(CouponCampOnlineListParam().apply {
                camp_id = detailId
            }.queryMap).request()

            withContext(Dispatchers.Main){
                couponList.value = couponRespond.data?.list
                if (respond.data != null){
                    productList.postValue(respond.data)
                } else {
                    productList.postValue(PlaceProductList().apply {
                        list = mutableListOf()
                        show_num = 8
                    })
                }
            }
        }, whenCatch = {
            LogUtils.e("$it")
        })
    }

    fun requestActList() {
        launchWithTryAsynchronous(whenTry = {
            val respond = mActivityService.campActivitiesList(CampActivitiesListParam().apply {
                camp_id = detailId
            }.queryMap).request()
            if(respond.data?.list?.isNotEmpty() == true){
                for(item in respond.data?.list!!){
                    item.parseData()
                }
            }
            withContext(Dispatchers.Main){
                actList.value = respond.data?.list
            }
        }, whenCatch = {
        })
    }


    fun requestPunchRecommendList() {
        launchWithTryAsynchronous(whenTry = {
            val respond = mPostingService.placeDetailPunchRecommend(CampPunchListParam().apply {
                this.camp_id = detailId
                this.page_size= 20
            }).request()

            if(respond.data?.list?.isNotEmpty() == true){
                for(item in respond.data?.list!!){
                    item.parseData()
                }
            }

            withContext(Dispatchers.Main){
                punchRecommendList.value = respond.data?.list
            }
        }, whenCatch = {
        })
    }


}